package cn.jeeweb.common.http;

import cn.jeeweb.common.flag.ObjectMark;
import cn.jeeweb.common.mvc.entity.DataEntity;
import cn.jeeweb.common.utils.ReflectionUtils;
import cn.jeeweb.common.utils.ServletUtils;
import cn.jeeweb.common.utils.fastjson.FastjsonPropertyPreFilter;
import cn.jeeweb.common.utils.fastjson.FastjsonUnXssFilter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description: 数据响应实体
 */
public class Response extends HashMap<String, Object> implements Serializable {
    public Response() {
        put("code", ResponseCode.OK_CODE);
        put("msg", "操作成功");
    }

    public Response putList(String key, List list, String includesProperties) {
        if (list.size() > 0) {
            FastjsonPropertyPreFilter fastjsonPropertyPreFilter = new FastjsonPropertyPreFilter(list.get(0).getClass().getClass(), includesProperties);
            FastjsonUnXssFilter fastjsonUnXssFilter = new FastjsonUnXssFilter();
            SerializeFilter[] filters = {fastjsonPropertyPreFilter, fastjsonUnXssFilter};
            String objectStr = JSON.toJSONString(list, filters);
            List<Map> dataList = JSON.parseObject(objectStr, List.class);
            put(key, dataList);
        } else {
            put(key, new ArrayList<Map>());
        }
        return this;
    }

    public Response putList(String key, List list) {
        if (list.size() > 0) {
            FastjsonUnXssFilter fastjsonUnXssFilter = new FastjsonUnXssFilter();
            SerializeFilter[] filters = {fastjsonUnXssFilter};
            String objectStr = JSON.toJSONString(list, filters);
            List<Map> dataList = JSON.parseObject(objectStr, List.class);
            put(key, dataList);
        } else {
            put(key, new ArrayList<Map>());
        }
        return this;
    }

    /**
     * 数据对象转换为Json对象，可以过滤字段
     *
     * @param object
     * @param includesProperties 可选需要的字段，null表示需要全部的字段，（仅对分布数据字段过滤。我没弄明白 By Akin）
     * @return
     */
    public Response putObject(Object object, String includesProperties) {
        if (object != null) {
            FastjsonUnXssFilter fastjsonUnXssFilter = new FastjsonUnXssFilter();
            String objectStr = null;
            if (includesProperties == null || includesProperties.isEmpty()) {
                objectStr = JSON.toJSONString(object, fastjsonUnXssFilter, SerializerFeature.WriteMapNullValue);
            } else {
                FastjsonPropertyPreFilter fastjsonPropertyPreFilter = new FastjsonPropertyPreFilter(object.getClass(), includesProperties);
                SerializeFilter[] filters = {fastjsonPropertyPreFilter, fastjsonUnXssFilter};
                objectStr = JSON.toJSONString(object, filters, SerializerFeature.WriteMapNullValue);
            }
            Map dataMap = JSON.parseObject(objectStr, Map.class);
            dataMap.remove("class");
            putAll(dataMap);
        }
        return this;
    }

    public Response putObject(Object object) {
        return putObject(object, null);
    }

    public static Response ok() {
        return ok(null, null);
    }

    public static Response ok(String msg) {
        return ok(msg, null);
    }

    public static Response ok(String msg, Object object) {
        return response(ResponseCode.OK_CODE, msg, object);
    }

    public static Response ok(String msg, Object object, String includesProperties) {
        return response(ResponseCode.OK_CODE, msg, object, includesProperties);
    }

    public static Response error(String msg) {
        return error(msg, null);
    }

    public static Response error(String msg, Object object) {
        return response(ResponseCode.ERROR_CODE, msg, object);
    }

    public static Response error(int errCode, String msg) {
        return response(errCode, msg, null);
    }

    public static Response response(int code, String failInfo) {
        return response(code, failInfo, null);
    }

    public static Response response(int code, String failInfo, Object object) {
        Response response = new Response();
        response.put("code", code);
        response.put("msg", failInfo);
        if (object != null) {
            if (object.getClass().isArray())
                response.put("records", object);
            else if (object instanceof ObjectMark){
                FastjsonUnXssFilter fastjsonUnXssFilter = new FastjsonUnXssFilter();
                String objectStr = JSON.toJSONString(object, fastjsonUnXssFilter, SerializerFeature.WriteMapNullValue);
                response.put("record", objectStr);
            } else
            response.putObject(object, null);
        }
        response.AddExecuteTime();
        return response;
    }

    public static Response response(int code, String failInfo, Object object, String includesProperties) {
        Response response = new Response();
        response.put("code", code);
        response.put("msg", failInfo);
        response.putObject(object, includesProperties);
        response.AddExecuteTime();
        return response;
    }

    /**
     * 返回之前的动作：加入接口执行时间。
     */
    private void AddExecuteTime() {
        HttpServletRequest request = ServletUtils.getRequest();
        if (request != null) {
            Object tt = request.getAttribute("xjs_startTime");
            if (tt != null) {
                long startTime = (Long) request.getAttribute("xjs_startTime");
                if (startTime > 0) {
                    long endTime = System.currentTimeMillis();
                    long executeTime = endTime - startTime;
                    put("executeTime", "" + executeTime);
                }
            }
        }
    }
}
